package com.easygoods.bean;

import com.bestvike.stone.core.lang.Convert;
import com.bestvike.stone.core.serialization.JsonSerializer;
import com.bestvike.stone.core.time.DateUtils;
import com.easygoods.entity.PayRecord;
import com.easygoods.enums.PayChannel;
import com.easygoods.enums.YNEnum;
import com.easygoods.external.wechat.pay.request.WeChatPayNotifyRequest;
import com.easygoods.external.wechat.pay.respon.WeChatOrderQueryResponse;
import com.easygoods.service.ConfigService;
import lombok.Data;
import org.apache.commons.lang.Validate;
import org.springframework.util.Assert;

import javax.validation.Validation;
import java.math.BigDecimal;
import java.util.Date;

/**
 * @author zhq
 * @date 2019/1/23
 */
@Data
public class PayOrderBean {
    private PayChannel payChannel;
    private String payTradeNo;//实际交易流水号
    private String orderId;//订单主键
    private String openid;
    private BigDecimal amount;
    private String feeType;
    private BigDecimal cashAmount;
    private String cashFeeType;
    private BigDecimal couponAmount;
    private Integer couponCount;
    private String bankType;
    private String merchantId;
    private String merchantName;
    private String attach;
    private Date payTime;
    private String remark;

    public static PayOrderBean fromWeChatNotify(WeChatPayNotifyRequest request) {
        Assert.notNull(request, "request can not be null");
        PayOrderBean bean = new PayOrderBean();
        bean.payChannel = PayChannel.WeChatPay;
        bean.payTradeNo = request.getTransactionId();
        bean.orderId = request.getOutTradeNo();
        bean.openid = request.getOpenid();
        bean.amount = Convert.toDecimal(request.getTotalFee()).divide(Convert.toDecimal(100), ConfigService.getMathContext());
        bean.feeType = Convert.toString(request.getFeeType());
        bean.cashAmount = Convert.toDecimal(request.getCashFee()).divide(Convert.toDecimal(100), ConfigService.getMathContext());
        bean.cashFeeType = Convert.toString(request.getCashFeeType());
        bean.couponAmount = Convert.toDecimal(request.getCouponCount()).divide(Convert.toDecimal(100), ConfigService.getMathContext());
        bean.couponCount = request.getCouponCount();
        OrderAttach orderAttach = JsonSerializer.deserialize(request.getAttach(), OrderAttach.class);
        if (orderAttach != null) {
            bean.merchantId = orderAttach.getMerchantId();
            bean.merchantName = orderAttach.getMerchantName();
        }
        bean.attach = request.getAttach();
        bean.payTime = DateUtils.fromString(request.getTimeEnd(), "yyyyMMddHHmmss");
        bean.remark = "微信回调";
        return bean;
    }

    public static PayOrderBean fromWeChatQuery(WeChatOrderQueryResponse response) {
        Assert.notNull(response, "response can not be null");
        PayOrderBean bean = new PayOrderBean();
        bean.payChannel = PayChannel.WeChatPay;
        bean.payTradeNo = response.getTransaction_id();
        bean.orderId = response.getOut_trade_no();
        bean.openid = response.getOpenid();
        bean.amount = Convert.toDecimal(response.getTotal_fee()).divide(Convert.toDecimal(100), ConfigService.getMathContext());
        bean.feeType = Convert.toString(response.getFee_type());
        bean.cashAmount = Convert.toDecimal(response.getCash_fee()).divide(Convert.toDecimal(100), ConfigService.getMathContext());
        bean.cashFeeType = Convert.toString(response.getCash_fee_type());
        bean.couponAmount = Convert.toDecimal(response.getCoupon_fee()).divide(Convert.toDecimal(100), ConfigService.getMathContext());
        bean.couponCount = Convert.defaultInteger(response.getCoupon_count());
        bean.bankType = response.getBank_type();
        OrderAttach orderAttach = JsonSerializer.deserialize(response.getAttach(), OrderAttach.class);
        if (orderAttach != null) {
            bean.merchantId = orderAttach.getMerchantId();
            bean.merchantName = orderAttach.getMerchantName();
        }
        bean.payTime = DateUtils.fromString(response.getTime_end(), "yyyyMMddHHmmss");
        bean.remark = "主动查询微信支付状态";
        return bean;
    }

    public PayRecord toPayRecord() {
        PayRecord payRecord = new PayRecord();
        payRecord.setId(this.payTradeNo);//
        payRecord.setPayChannel(this.payChannel.name());
        payRecord.setOrderId(this.orderId);
        payRecord.setPayOpenId(this.openid);//
        payRecord.setAmount(this.amount);
        payRecord.setFeeType(this.feeType);
        payRecord.setCashAmount(this.cashAmount);
        payRecord.setCashFeeType(this.cashFeeType);
        payRecord.setCouponAmount(this.couponAmount);
        payRecord.setCouponCount(this.couponCount);
        payRecord.setBankType(this.bankType);
        payRecord.setMerchantId(this.merchantId);
        payRecord.setMerchantName(this.merchantName);
        payRecord.setPayTime(this.payTime);
        payRecord.setRemark(this.remark);
        payRecord.setFinish(YNEnum.N.name());
        return payRecord;
    }

    public void assertValid() {
        Assert.notNull(this.payChannel, "支付渠道不能为空");
        Assert.hasText(this.payTradeNo, "支付流水号不能为空");
        Assert.hasText(this.orderId, "订单号不能为空");
        Assert.hasText(this.openid, "支付人不能为空");
        Assert.notNull(this.amount, "支付金额不能为空");
        Assert.hasText(this.merchantId, "商户主键不能为空");
        Assert.isTrue(this.amount.compareTo(BigDecimal.ZERO) >= 0, "支付金额不能为负数");
    }
}
